﻿using ET.HelloWorld.Hotfix.Handlers;
using ETHotfix;
using ETModel;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using UnityEngine;
using BVector3 = BulletSharp.Math.Vector3;

namespace ET.HelloWorld.Hotfix.Components {

    /// <summary>
    /// 单位信息同步组件的启动
    /// </summary>
    [ObjectSystem]
    public class UnitInfoSyncAwake : AwakeSystem<UnitInfoSyncComponent> {
        public override void Awake(UnitInfoSyncComponent self) {
            self.Awake();
        }
    }
    /// <summary>
    /// 单位信息同步组件的停止
    /// </summary>
    [ObjectSystem]
    public class UnitInfoSyncDestroy : DestroySystem<UnitInfoSyncComponent> {
        public override void Destroy(UnitInfoSyncComponent self) {
            self.Dispose();
        }
    }

    /// <summary>
    /// 调试信息同步助手
    /// </summary>
    public class UnitInfoSyncComponent : Component {
        /// <summary>
        /// 本次要同步的单位ID
        /// </summary>
        private ConcurrentDictionary<long, bool> SyncToClientUnitId = new ConcurrentDictionary<long, bool>();
        /// <summary>
        /// 本次要同步的单位矩阵
        /// </summary>
        private ConcurrentDictionary<long, Vector3> SyncToClientCenterPosition = new ConcurrentDictionary<long, Vector3>();
        /// <summary>
        /// 本次要同步的单位矩阵
        /// </summary>
        private ConcurrentDictionary<long, Quaternion> SyncToClientRotation = new ConcurrentDictionary<long, Quaternion>();
        /// <summary>
        /// 本次要同步的单位矩阵
        /// </summary>
        private ConcurrentDictionary<long, Vector3> SyncToClientScale = new ConcurrentDictionary<long, Vector3>();

        private M2C_UnitInfoSync ToClientMsg = new M2C_UnitInfoSync();
        public int SyncInterval = 30;

        /// <summary>
        /// 要求同步单位的世界矩阵
        /// </summary>
        /// <param name="id"></param>
        /// <param name="vertices"></param>
        /// <param name="indices"></param>
        public void UpdateUnitMeshSync(long id, ref Vector3 centerPos, ref Quaternion rotation, ref Vector3 scale) {
            SyncToClientUnitId[id] = true;
            SyncToClientCenterPosition[id] = centerPos;
            SyncToClientRotation[id] = rotation;
            SyncToClientScale[id] = scale;
        }



        private Thread SyncToClientTh;
        private AutoResetEvent SyncToClientThExitEvent;
        private AutoResetEvent MainThreadCompletEvent;
        public void Awake() {
            EndThread();
            SyncToClientThExitEvent = new AutoResetEvent(false);
            MainThreadCompletEvent = new AutoResetEvent(false);
            SyncToClientTh = new Thread(new ThreadStart(SyncToClientProcess));
            SyncToClientTh.Start();
        }
        public override void Dispose() {
            EndThread();
            base.Dispose();
        }
        private void EndThread() {
            if (SyncToClientTh != null) {
                MainThreadCompletEvent.Set();
                SyncToClientThExitEvent.Set();
                if (SyncToClientTh.ThreadState != ThreadState.Stopped) {
                    try {
                        SyncToClientTh.Abort();
                    } catch { }
                }
                SyncToClientTh = null;

                MainThreadCompletEvent.Dispose();
                MainThreadCompletEvent = null;

                SyncToClientThExitEvent.Dispose();
                SyncToClientThExitEvent = null;
            }
        }
        private void SyncToClientProcess() {
            while (!SyncToClientThExitEvent.WaitOne(SyncInterval)) {
                //等待时间到了还没收到停止信号则继续下个循环
                OneThreadSynchronizationContext.Instance.Post((object state) => {
                    //给主线程去做,单线程来处理
                    OnceSyncDebugInfoToClient();
                    MainThreadCompletEvent.Set();
                }, null);
                MainThreadCompletEvent.WaitOne();
            }
        }


        /// <summary>
        /// 一次同步,返回是否广播了数据
        /// </summary>
        /// <returns></returns>
        private bool OnceSyncDebugInfoToClient() {


            ToClientMsg.UnitSyncInfos.Clear();

            var keys = SyncToClientUnitId.Keys;
            foreach (var id in keys) {
                var unitInfo = new UnitSyncInfo() { Id = id };

                //同步单位的位置
                Vector3 pos;
                if (!SyncToClientCenterPosition.TryGetValue(id, out pos)) {
                    continue;
                }
                unitInfo.SetCenterPosition(ref pos);

                //同步单位的旋转
                Quaternion rotation;
                if (!SyncToClientRotation.TryGetValue(id, out rotation)) {
                    continue;
                }
                unitInfo.SetRotation(ref rotation);

                //同步单位的缩放
                Vector3 scale;
                if (!SyncToClientScale.TryGetValue(id, out scale)) {
                    continue;
                }
                unitInfo.SetScale(ref scale);

                ToClientMsg.UnitSyncInfos.Add(unitInfo);
            }
            SyncToClientUnitId.Clear();
            SyncToClientCenterPosition.Clear();
            SyncToClientRotation.Clear();
            SyncToClientScale.Clear();


            if (ToClientMsg.UnitSyncInfos.Count > 0) {
                //任何一个信息需要同步,都广播
                //MessageHelper.Broadcast(ToClientMsg);
                ToClientMsg.MapBroadcastAllPlayers();
                return true;
            }
            return false;

        }
    }
}
